<template>
  <!--  菜单模块页面-->
  <div class="page">
    <div
      style="font-size: 28px;display: flex;align-items: center;justify-content: left;width: 100vw;color: #7f7f7f;   cursor: pointer;">
      <p style="min-width: 5%;" :key="item.name" @click="ssBtn(item)" v-for="item in tableText"
         :class="menuBox==item.code ? 'menuBox' : ' '">{{item.name}}
        <i class="iconfont iconjinruyou" :class="menuBox==item.code ? 'menuBox' : ' '"
           style="color: #7f7f7f;font-size: 28px;font-weight: 600"></i>
      </p>
    </div>
    <div class="page_main">
      <el-button icon="el-icon-plus" @click="handleAdd({})" class="common_btn-small">添加菜单</el-button>
      <el-button icon="el-icon-sort" @click.stop="handleSortMonitorPoint()" class="common_btn-small">
        菜单排序
      </el-button>
      <transition name="slide-left">
        <div v-show="menuBox===1">

          <!-- table -->
          <div class="cardBox">
            <el-divider><span style="font-size: 25px; color:#1990FE">选择一级菜单</span></el-divider>
            <el-card shadow="hover" :class="damageType == item.id ? 'select_card' : 'hover_card'"
                     @click.native="changeDamageType(item,1)" v-for="item in tableList" :key="item.name">
              <div class="divTitle">
                <i class="iconfont" :class="item.menuIcon" style="font-size: 20px"></i>
                <span class="zh_name_view">{{ item.name }}</span>
              </div>
              <p style="font-size: 12px;margin-top: 30px">描述：{{item.description}}</p>
              <!--              v-if="damageType == item.id " -->
              <div style="margin-bottom: 20px">
                <button type="text"
                        class="btn_edit"
                        @click.stop="handleEdit(item, item._level)" style="margin-right: 10px">
                  修改
                </button>
                <el-popconfirm title="确定删除该菜单吗？" @confirm="handleDelete(item.id)">
                  <button class="btn_delete" slot="reference" @click.stop>刪除</button>
                </el-popconfirm>


              </div>
            </el-card>
          </div>
          <div v-for="item in tableList" :key="item.name">
          </div>
        </div>
      </transition>
      <transition name="slide-left">
        <div v-show="menuBox===2">
          <!-- table -->
          <div class="cardBox">
            <el-divider><span style="font-size: 25px; color:#1990FE">选择二级菜单</span></el-divider>
            <div v-for="item in tableList" :key="item.name" style="width: 100%; ">
              <div v-if="item.id==secondIds" style="width: 100%; display: flex;flex-wrap: wrap">
                <el-card shadow=" hover
              " :class="damageType3 == child1.id ? 'select_card' : 'hover_card'"
                         @click.native="changeDamageType(child1,2)" v-for="child1 in item.subMenu"
                         :key="child1.name">
                  <div class="divTitle">
                    <i class="iconfont" :class="child1.menuIcon" style="font-size: 20px"></i>
                    <span class="zh_name_view">{{ child1.name }}</span>
                  </div>
                  <p style="font-size: 12px;margin-top: 30px">{{child1.description}}</p>
                  <div style="margin-bottom: 20px">
                    <button type="text"
                            class="btn_edit"
                            @click.stop="handleEdit(child1, child1._level)" style="margin-right: 10px">
                      修改
                    </button>
                    <el-popconfirm title="确定删除该菜单吗？" @confirm="handleDelete(child1.id)">
                      <button class="btn_delete" slot="reference" @click.stop>刪除</button>
                    </el-popconfirm>

                  </div>
                </el-card>
              </div>
            </div>

          </div>
        </div>
      </transition>

      <transition name="slide-left">
        <div v-show="menuBox===3">
          <!-- table -->
          <div class="cardBox">
            <el-divider><span style="font-size: 25px; color:#1990FE">选择三级菜单</span></el-divider>
            <div v-for="item in tableList" :key="item.name" style="width: 100%;">
              <div v-for="child in item.subMenu" :key="child.name">
                <div v-if="damageType3 == child.id" style="display: flex;flex-wrap: wrap">
                  <div v-if="child.subMenu==null" style="display: flex;flex-wrap: wrap">
                    <p style="font-weight: bold;font-size: 20px;color: #1990FE;margin: auto">没有第三级菜单</p>
                  </div>

                  <el-card shadow="hover" :class="damageType3 == child2.id ? 'select_card2' : 'hover_card'"
                           @click.native="changeDamageType(child2,3)" v-for="child2 in child.subMenu"
                           :key="child2.name">
                    <div class="divTitle">
                      <i class="iconfont" :class="child2.menuIcon" style="font-size: 20px"></i>
                      <span class="zh_name_view">{{ child2.name }}</span>
                    </div>
                    <p style="font-size: 12px;margin-top: 30px">{{child2.description}}</p>
                    <div style="margin-bottom: 20px">
                      <button type="text"
                              class="btn_edit"
                              @click.stop="handleEdit(child2, child2._level)" style="margin-right: 10px">
                        修改
                      </button>
                      <el-popconfirm title="确定删除该菜单吗？" @confirm="handleDelete(child2.id)">
                        <button class="btn_delete" slot="reference" @click.stop>刪除</button>
                      </el-popconfirm>

                    </div>
                  </el-card>


                </div>
              </div>
            </div>

          </div>
        </div>
      </transition>

    </div>
    <!-- 新增编辑弹窗 -->
    <el-dialog
      :close-on-click-modal="false"
      :title="dialogTitle"
      :visible.sync="isShowDialog"
      width="600px">
      <!-- 具体form表单 -->
      <el-form label-position="right" ref="form" :rules="rules" :model="form" label-width="80px" class="form_width-200">
        <el-form-item label="上级菜单" v-if="form.parentId">
          <div class="width_200">{{form.__parentName}}</div>
        </el-form-item>
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model.trim="form.name" placeholder="输入菜单名称" :maxlength="20"></el-input>
        </el-form-item>
        <!-- 添加子集时才是必填 -->
        <!-- 若是一级菜单修改，并且用子集时 禁止修改 -->
        <el-form-item label="URL" :prop="form._level === 2 ? 'url' : ''">
          <el-input v-model.trim="form.url" placeholder="输入URL" :maxlength="50"
                    :disabled="form.subMenu && form.subMenu.length && form._level === 1"></el-input>
        </el-form-item>
        <el-form-item label="菜单图标" prop="menuIcon" class="menu_icon">
          <span class="menu_icon-wrap flex-center">
            <i class="iconfont" :class="form.menuIcon"></i>
          </span>
          <el-select class="menu_icon-select" v-model.trim="form.menuIcon" filterable placeholder="菜单图标">
            <el-option :value="item.font_class" v-for="item in iconList" :key="item.font_class">
              <i style="float: left" class="iconfont" :class="item.font_class"></i>
              <span style="float: right">{{ item.font_class }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="打开方式" prop="tabFlag">
          <el-select v-model.trim="form.tabFlag" placeholder="请选择打开方式">
            <el-option
              v-for="item in EnumSysFlagList"
              :key="item.code"
              :label="item.name"
              :value="item.code"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input v-model.trim="form.description" type="textarea" placeholder="描述" :maxlength="50"></el-input>
        </el-form-item>
        <el-form-item label="许可标识" v-if="form._level === 3">
          <el-input v-model.trim="form.permission" placeholder="菜单权限标识,eg sys:syslog:view"></el-input>
        </el-form-item>
        <el-form-item label="排序值">
          <el-input v-model.trim="form.weight" placeholder="值越大越靠前" type="number"></el-input>
        </el-form-item>
      </el-form>
      <!-- 操作按钮 -->
      <span slot="footer" class="dialog-footer">
<!--        <el-button class="common_btn-white" @click="isShowDialog = false">取消</el-button>-->
        <el-button class="common_btn-defalut" type="primary" @click="validateForm">确定</el-button>
      </span>
    </el-dialog>
    <!--    排序-->
    <el-dialog title="菜单排序" :visible.sync="isShowDialog2" :close-on-click-modal="false" width="220px">
      <div style="text-align: center;color: #ff4d51;margin-bottom: 10px;font-size: 15px">从上至下进行排序，拖拽改变顺序，提交后生效！</div>
      <el-tree
        :data="monitorSortList"
        node-key="id"
        default-expand-all
        highlight-current
        :allow-drop="allowDrop"
        draggable>
        <span class="custom-tree-node" slot-scope="{ node }">
            <span>
                <i class="el-icon-s-flag" style="margin-right: 10px;color: #1990FE"></i>{{ node.label }}
            </span>
        </span>
      </el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button class="common_btn-white" @click="isShowDialog2 = false">取消</el-button>
        <el-button class="common_btn-defalut" type="primary" @click="sortSubmit">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  import {menuUpdate, menuAdd, menuDelete, monitorPointSort} from '@/services/model/authority-mgmt'
  import {getMenuTree} from '@/services/model/user'
  import {getDictData} from '@/services/model/common'
  import {glyphs} from '@/assets/icon-font/iconfont.json'
  import Format from '@/utils/format'
  // form表单校验规则
  const RULES = {
    name: {required: true, message: '请输入菜单名称'},
    url: {required: true, message: '请输入URL'},
    menuIcon: {required: true, message: '请选择图标', trigger: 'change'},
    tabFlag: {required: true, message: '请打开方式', trigger: 'change'},
  }
  export default {
    data() {
      return {
        secondIds: '',
        monitorSortList: [],
        isShowDialog2: false,

        tableText: [{
          name: '第一级菜单',
          code: 1
        }, {
          name: '第二级菜单',
          code: 2
        }, {
          name: '第三级菜单',
          code: 3
        }],
        menuBox: 1,
        damageType: '1400763334765178881',
        damageType2: '1400767758816374786',
        damageType3: '',
        // 替换字段
        defaultProps: {
          children: 'subMenu',
          label: 'name'
        },
        // 表单
        form: {},
        form2: {},
        // 二级菜单储存排序值
        subMenuList2: [],
        // 三级菜单排序值
        subMenuList3: [],
        rules: RULES,
        // 展示弹窗
        isShowDialog: false,
        // 图标列表
        iconList: [],
        // 接口获取 打开方式
        EnumSysFlagList: [],
      }
    },
    filters: {
      // 时间格式化
      formatTimer(timer) {
        return Format(new Date(timer))
      }
    },
    computed: {
      // 树形菜单
      tableList() {
        let menu = this.$store.state.nodeList
        // 设置层级
        const _setLevel = (list, index = 1) => list.map(x => {
          x._level = index
          x.subMenu && _setLevel(x.subMenu, index + 1)
          return x
        })
        return _setLevel(menu)

      },
      // 弹窗的title
      dialogTitle() {
        return this.form.id ? '编辑菜单' : '新增菜单'
      }
    },
    created() {
      this.iconList = glyphs.map(x => ({...x, font_class: 'icon' + x.font_class}))
    },
    mounted() {
      this.queryDictData()
    },
    methods: {
      ssBtn(item) {
        this.menuBox = item.code
        this.dividerTitle = item.name


      },
      //拖拽时判定目标节点能否被放置。type 参数有三种情况：'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
      allowDrop(draggingNode, dropNode, type) {
        //限制拖入节点内
        return type !== 'inner'
      },
      //排序确定事件
      async sortSubmit() {
        let name = []
        let i = this.monitorSortList.length
        //更新排序值

        this.monitorSortList.map(x => {
          x.weight = i
          name.push(x)
          i--
        })
        let res = await monitorPointSort(name)
        if (res.code === 200) {
          this.$notify({
            type: 'success',
            title: '提示',
            message: '排序调整成功！'
          })

          this.isShowDialog2 = false
          this.queryList()
          this.$nextTick(() => {
            if (this.menuBox == 2) {
              this.$set(this.subMenuList2)
            } else if (this.menuBox == 3) {
              this.$set(this.subMenuList3)

            }

          })
        }
      },

      // 打开排序弹窗
      handleSortMonitorPoint() {
        if (this.menuBox == 2) {
          this.$set(this.subMenuList2)
        } else if (this.menuBox == 3) {
          this.$set(this.subMenuList3)
        }
        if (this.menuBox == 1) {
          this.monitorSortList = this.tableList.map(x => {
            return {id: x.id, weight: x.weight, label: x.name}
          })
        } else if (this.menuBox == 2) {
          this.monitorSortList = this.subMenuList2.map(x => {
            return {id: x.id, weight: x.weight, label: x.name}
            this.$set(this.subMenuList2,)
          })
        } else if (this.menuBox == 3) {
          this.monitorSortList = this.subMenuList3.map(x => {
            return {id: x.id, weight: x.weight, label: x.name}
          })
        }
        this.isShowDialog2 = true
      },
      // 一级菜单选中
      changeDamageType(item, level) {
        if (level == 1) {
          this.subMenuList2 = item.subMenu
          this.secondIds = item.id
          this.tableText[1].name = item.name
        } else if (level == 2) {
          this.subMenuList3 = item.subMenu
          this.tableText[2].name = item.name
        }
        if (this.menuBox < 3) {
          this.damageType = item.id;
          this.damageType2 = item.id;
          this.damageType3 = item.id;
          this.menuBox = item._level + 1
          this.form = {
            parentId: item.id,
            __parentName: item.name,
            tabFlag: this.EnumSysFlagList[0]?.code,
            _level: level
          }
          this.form2 = {
            parentId: item.id,
            __parentName: item.name,
            tabFlag: this.EnumSysFlagList[0]?.code,
            _level: level
          }
        }
      },

      // 通用获取枚举方法
      async queryDictData() {
        const {data} = await getDictData({enumName: 'EnumMenuTabFlag'})
        this.EnumSysFlagList = data || []
      },
      async handleDelete(id) {
        await menuDelete({id})
        this.$notify({
          title: '提示',
          message: '删除成功',
          type: 'success'
        })
        this.queryList()
        this.$nextTick(() => {
          if (this.menuBox == 2) {
            this.$set(this.subMenuList2)


          } else if (this.menuBox == 3) {
            this.$set(this.subMenuList3)


          }

        })
      },
      // 添加菜单 level当前数据对应的tree层级
      handleAdd() {
        // return
        this.isShowDialog = true
        this.form={}
        this.form._level = this.menuBox
        this.$nextTick(() => {
          this.$refs.form.clearValidate()
        })
      },
      // 编辑 level 当前操作对象相对于tree的层级
      handleEdit(item, level) {
        this.form = JSON.parse(JSON.stringify(item))
        this.form._level = level
        this.isShowDialog = true
        this.$nextTick(() => {
          this.$refs.form.clearValidate()
        })
      },
      // 表单提交
      validateForm() {
        this.$refs.form.validate((valid) => {
          valid && this.submitData()
        })
      },
      // 新增编辑提交数据
      async submitData() {
        // 根据ID判断使用新增还是编辑
        const AJAX_ACTION = this.form.id ? menuUpdate : menuAdd
        await AJAX_ACTION(this.form)
        this.$notify({
          type: 'success',
          title: '提示',
          message: this.form.id ? '编辑成功' : '添加成功'
        })
        this.isShowDialog = false

        this.queryList()
      },
      // 数据查询
      async queryList() {
        const {data} = await getMenuTree()
        this.$store.commit('setState', {name: 'nodeList', value: data || []})
      }
    }
  }
</script>
<style lang="less" scoped>
  .page {
    height: 100%;
    padding: 24px;
    overflow-x: hidden;
    overflow-y: auto;

    .menu_icon-wrap {
      vertical-align: middle;
      display: inline-flex;
      width: 40px;
      height: 40px;
      border: 1px solid #DCDFE6;
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px;
      border-right: none;

      i {
        font-size: 22px;
      }
    }

    .menu_icon-select {
      width: calc(100% - 40px);

      /deep/ input {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
        vertical-align: middle;
      }
    }

    .page_top {
      font-weight: 600;
      font-size: 20px;
      color: #23252C;
      background-color: #ffffff;
      height: 50px;
      padding: 0 20px;
      border-radius: 8px;
      display: flex;
      align-items: center;
      margin-bottom: 16px;
    }
  }

  .page_header {
    padding: 10px 40px;
    background-color: #EEF4FF;
    color: #6680C1;

    & > em {
      padding-left: 20px;
    }

    .page_header-wrap {
      width: 70vw;
      display: flex;

      & > div {
        padding-left: 20px;
      }
    }
  }

  /deep/ .menu_tree {
    padding: 0 40px 40px;
    border-radius: 8px;

    .el-tree-node__content {
      height: 40px;
      border-bottom: 1px solid #3cc891;
    }

    .menu_node {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .menu_node-label {
        // width: 300px;
        // flex-shrink: 0;
      }

      .menu_node-content {
        display: flex;
        width: 70vw;
      }
    }
  }
</style>
<style lang="less" scoped>
  .cardBox {
    width: 100%;
    /*height: 100vh;*/
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;

  }

  .el-card {
    height: 154px;
    overflow: auto;
    padding-top: 20px;
    width: 18%;
    display: flex;
    align-items: center;
    justify-content: left;
    margin: 1%;
    font-size: 120%;
    box-shadow: 0px 0px 8px #757575;
    background: #ffffff;
    color: #1990FE;
    box-shadow: none;
    border: 1px solid #1990FE !important;

    .el-divider {
      .el-divider__text {
        color: white;
      }
    }
  }

  .select_card {
    background: #29597f !important;
    font-size: 200%;
    font-weight: 600;
    transition: height 0.8s;
    height: 180px;
    color: white !important;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 2px 2px 2px #6d6d6d !important;
    overflow: hidden;

    .divTitle {
      transition: transform 0.8s;
      transform: translateY(-10px);

    }

  }

  .select_card2 {
    width: 30% !important;
    background: #29597f !important;
    font-size: 200%;
    font-weight: 600;
    transition: height 0.8s;
    height: 180px;
    color: white !important;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 2px 2px 2px #6d6d6d !important;
    overflow: hidden;

    .divTitle {
      transition: transform 0.8s;
      transform: translateY(-10px);
    }
  }

  .hover_card:hover {
    transition: 0.5s font-size;
    font-size: 180%;
    color: white !important;
    font-weight: 600;
  }

  .el-card:hover {
    background: #29597f !important;

    .pBox {
      color: white !important;
    }
  }

  .zh_name_view {
    display: inline-block;
    margin-left: 15px;
  }

  .menuBox {
    font-weight: 600;
    color: #1990FE !important;
    cursor: pointer;
  }
</style>
<!--2. 自定义两组样式，来控制transition 内部的元素实现动画-->
<style>
  .slide-left-enter-active {
    transition: all 0.8s ease;
  }

  .slide-left-leave-active {
    transition: all 0s ease;
  }

  .slide-left-enter
    /* .slide-fade-leave-active for below version 2.1.8 */
  {
    transform: translateY(100%);
    /*transform: rotate(360deg);*/
    opacity: 1;
  }

  .slide-left-leave-to {
    transform: translateY(-100%);

    /*transform: rotate(-360deg);*/
    opacity: 1;
  }
</style>
